/********************************
 * auth : sunqiang
 * date : 20170118
 * desp : hash calculate
 * 			reference: http://blog.chinaunix.net/uid-20558494-id-2803048.html
 * ****************************/

#include <stdio.h>
#include "sn_hash.h"

static unsigned long  hash_table[0x500];

void
sn_prepare_hash_table()
{
	unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i;

	for( index1 = 0; index1 < 0x100; index1++ )
	{
		for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 )
		{
			unsigned long temp1, temp2;

			seed = (seed * 125 + 3) % 0x2AAAAB;
			temp1 = (seed & 0xFFFF) << 0x10;

			seed = (seed * 125 + 3) % 0x2AAAAB;
			temp2 = (seed & 0xFFFF);

			hash_table[index2] = ( temp1 | temp2 );
		}
	}
}

unsigned long
sn_calcu_hash_string(u_char *str)
{
	unsigned char *key  = (unsigned char *)str;
	unsigned long seed1 = 0x7FED7FED;
	unsigned long seed2 = 0xEEEEEEEE;
	unsigned long dwHashType = 1;
	int ch      = *key;

	dwHashType = ch % 3;

	while (*key) {
		ch = *key++;

		seed1 = hash_table[(dwHashType << 8) + ch] ^ (seed1 + seed2);
		seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
	}

	return seed1;
}
